#include "MapCanvas.h"
#include "MapRenderer.h"
#include "Map.h"
#include "MapTool.h"
#include "MapCanvasItem.h"
#include "CompassItem.h"
#include "CompassRender.h"
#include "MapToolPan.h"
#include "MapToolZoom.h"
#include "MapToolSelectPolygon.h"
#include "MapToolSelectRctangle.h"
#include "MapToolSelectPoint.h"
#include "MapToolDrawPolygon.h"
#include "MeasureTool.h"
#include "MapControlConfig.h"
#include "ScaleItem.h"
#include <QtGlobal>
#include <QApplication>
#include <QCursor>
#include <QDir>
#include <QFile>
#include <QKeyEvent>
#include <QMouseEvent>
#include <QPainter>
#include <QPaintEvent>
#include <QPixmap>
#include <QRect>
#include <QTextStream>
#include <QResizeEvent>
#include <QString>
#include <QStringList>
#include <QWheelEvent>
#include <QGraphicsScene>
#include <QToolBar>
#include <QAction>
#include <QMetaType>
#include <TGS/MapControl2.0/RendererList.h>
#include <TGS/MapControl2.0/MapToPixel.h>
#include <TGS/MapControl2.0/MapActions.h>
#include <TGS/MapControl2.0/MapToolBar.h>
#include <TGS/MapControl2.0/MapToolType.h>
#include <TGS/GeoMath2.0/Polygon.h>
#include <math.h>

namespace TGS{
namespace MapControl{


/**  @deprecated to be deleted, stuff from here should be moved elsewhere */
class MapCanvas::CanvasProperties
{
public:

	CanvasProperties() : mouseButtonDown( false ), panSelectorDown( false ) { }

	//!Flag to indicate status of mouse button
	bool mouseButtonDown;

	//! Last seen point of the mouse
	QPoint mouseLastXY;

	//! Beginning point of a rubber band
	QPoint rubberStartPoint;

	//! Flag to indicate the pan selector key is held down by user
	bool panSelectorDown;

};


MapCanvas::MapCanvas( QWidget * parent)
	: QGraphicsView( parent )
	, _canvasProperties( new CanvasProperties )
	, _newSize( QSize() )
	, _painting( false )
	, _antiAliasing( false )
	, _compass(nullptr)
{	
	_scene = new QGraphicsScene();
	setScene(_scene);
	setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
	setVerticalScrollBarPolicy( Qt::ScrollBarAlwaysOff );

	_mapActions = new MapActions(this);
	_mapToolBar = new MapToolBar(_mapActions, this);
	setMapToolBarVisible(false);
	createMapTools(_mapActions);
	setMapTool(_mapTools.pan);
	connectActionsSignalSlot();

	_drawing = false;
	_frozen = false;

	setWheelAction( WheelZoom );

	// by default, the canvas is rendered
	_renderFlag = true;

	setMouseTracking( true );
	setFocusPolicy( Qt::StrongFocus );

	_map = new Map();
	_scene->addItem( _map );
	_scene->update(); // porting??
	moveCanvasContents( true );
	_map->resize( size() );

	_compass = new CompassItem(":/Resources/image/compass.png");
	_scene->addItem(_compass);
	_scaleItem = new ScaleItem(_map);
	_scene->addItem(_scaleItem);

	_mapCoordinateItem = new MapCoordinateItem();
	connect(this, SIGNAL(mapCoordinate(double, double)), 
		_mapCoordinateItem, SLOT(mapCoordinate(double, double)));
	connect(this, SIGNAL(screenSizeChanged(const QSize&)), 
		_mapCoordinateItem, SLOT(screenSizeChanged(const QSize&)));
	_scene->addItem(_mapCoordinateItem);

	Envelope envelope(0, 0, 200, 200);
	setExtent(envelope);
	setCanvasColor(QColor(0xff,0xff,0xff,255));

	qRegisterMetaType<TGS::GeoMath::Polygon>("TGS::GeoMath::Polygon");
	qRegisterMetaType<TGS::GeoMath::Envelope>("TGS::GeoMath::Envelope");
	qRegisterMetaType<TGS::GeoMath::Point>("TGS::GeoMath::Point");
} 


MapCanvas::~MapCanvas()
{
	if ( _mapTool )
	{
		_mapTool->deactivate();
		_mapTool = nullptr;
	}
	_lastNonZoomMapTool = nullptr;

	if(nullptr != _scene)
	{
		// delete canvas items prior to deleteing the canvas
		// because they might try to update canvas when it's
		// already being destructed, ends with segfault
		QList<QGraphicsItem*> list = _scene->items();
		QList<QGraphicsItem*>::iterator it = list.begin();
		while ( it != list.end() )
		{
			QGraphicsItem* item = *it;
			delete item;
			it++;
		}

		delete _scene;
		_scene = nullptr;
	}

	
} 

void MapCanvas::enableAntiAliasing( bool theFlag )
{
	_antiAliasing = theFlag;
	_map->enableAntiAliasing( theFlag );
}

void MapCanvas::useImageToRender( bool theFlag )
{
	_map->useImageToRender( theFlag );
	refresh();
}

Map* MapCanvas::map()
{
	return _map;
}

MapRenderer* MapCanvas::mapRenderer()
{
	return _map->mapRenderer();
}

const MapRenderer* MapCanvas::mapRenderer() const
{
	return _map->mapRenderer();
}

double MapCanvas::scale()
{
	return _map->mapRenderer()->scale();
} 

bool MapCanvas::isDrawing()
{
	return _drawing;
} 


// return the current coordinate transform based on the extents and
// device size
const MapToPixel * MapCanvas::getCoordinateTransform()
{
	return _map->mapRenderer()->coordinateTransform();
}

void MapCanvas::refresh()
{
	// we can't draw again if already drawing...
	if ( _drawing )	return;

	_drawing = true;

	if ( _renderFlag && !_frozen )
	{
		// Tell the user we're going to be a while
		//QApplication::setOverrideCursor( Qt::WaitCursor );

		emit renderStarting();

		_map->render();

		emit renderComplete();
		// notifies current map tool
		if ( _mapTool )	_mapTool->renderComplete();

		// Tell the user we've finished going to be a while
		//QApplication::restoreOverrideCursor();
	}

	_drawing = false;
} 

void MapCanvas::updateMap()
{
	if ( _map )
	{
		_map->updateContents();
	}
}

//the format defaults to "PNG" if not specified
void MapCanvas::saveAsImage( QString theFileName, QPixmap * theQPixmap, QString theFormat )
{
	//
	//check if the optional QPaintDevice was supplied
	//
	if ( theQPixmap != NULL )
	{
		// render
		QPainter painter;
		painter.begin( theQPixmap );
		_map->mapRenderer()->render( &painter );
		painter.end();

		theQPixmap->save( theFileName, theFormat.toLocal8Bit().data() );
	}
	else //use the map view
	{
		QPixmap *pixmap = dynamic_cast<QPixmap *>( &_map->paintDevice() );
		if ( !pixmap ) return;

		pixmap->save( theFileName, theFormat.toLocal8Bit().data() );
	}	
}

MapCanvas::Envelope MapCanvas::extent() const
{
	return _map->mapRenderer()->extent();
}

void MapCanvas::setExtent(const Envelope& rectangle )
{
	if ( _drawing )
	{
		return;
	}  

	if(Envelope::Equal(rectangle, _map->mapRenderer()->extent())) return;

	if ( rectangle.isEmpty() )
	{
		Envelope current = extent();
		Envelope e( Point(  rectangle.getCenter().getX() - current.getWidth() / 2.0, 
							rectangle.getCenter().getY() - current.getHeight() / 2.0 ),
					Point(	rectangle.getCenter().getX() + current.getWidth() / 2.0, 
							rectangle.getCenter().getY() + current.getHeight() / 2.0 ) );
		_map->mapRenderer()->setExtent( e );
	}
	else
	{
		_map->mapRenderer()->setExtent( rectangle );
	}
	emit extentChanged(_map->mapRenderer()->extent());
	updateScale();
	updateCanvasItemPositions();
	refresh();
} 

void MapCanvas::updateScale()
{
	double scale = _map->mapRenderer()->scale();

	emit scaleChanged( scale );
}

void MapCanvas::zoomToFullExtent()
{
	fullExtent();
}

void MapCanvas::keyPressEvent( QKeyEvent * e )
{
	if ( _drawing )
	{
		e->ignore();
	}

	emit keyPressed( e );

	if ( _canvasProperties->mouseButtonDown || _canvasProperties->panSelectorDown )
		return;

	QPainter paint;
	QPen     pen( Qt::gray );
	Point ll, ur;

	if ( ! _canvasProperties->mouseButtonDown )
	{
		// Don't want to interfer with mouse events

		Envelope currentExtent = _map->mapRenderer()->extent();
		double dx = qAbs(( currentExtent.getMaxX() - currentExtent.getMinX() ) / 4 );
		double dy = qAbs(( currentExtent.getMaxY() - currentExtent.getMinY() ) / 4 );

		switch ( e->key() )
		{
		case Qt::Key_Right:

			currentExtent.setMinX( currentExtent.getMinX() - dx );
			currentExtent.setMaxX( currentExtent.getMaxX() - dx );
			setExtent( currentExtent );
			refresh();
			break;

		case Qt::Key_Left:

			currentExtent.setMinX( currentExtent.getMinX() + dx );
			currentExtent.setMaxX( currentExtent.getMaxX() + dx );
			setExtent( currentExtent );
			refresh();
			break;

		case Qt::Key_Down:
			currentExtent.setMaxY( currentExtent.getMaxY() + dy );
			currentExtent.setMinY( currentExtent.getMinY() + dy );
			setExtent( currentExtent );
			refresh();
			break;

		case Qt::Key_Up:
			currentExtent.setMaxY( currentExtent.getMaxY() - dy );
			currentExtent.setMinY( currentExtent.getMinY() - dy );
			setExtent( currentExtent );
			refresh();
			break;
		case Qt::Key_Space:
			if ( ! e->isAutoRepeat() )
			{
				_canvasProperties->panSelectorDown = true;
				_canvasProperties->rubberStartPoint = _canvasProperties->mouseLastXY;
			}
			break;

		case Qt::Key_PageUp:
			zoomIn();
			break;

		case Qt::Key_PageDown:
			zoomOut();
			break;

		default:
			if ( _mapTool )
			{
				_mapTool->keyPressEvent( e );
			}
			e->ignore();

		}
	}
} //keyPressEvent()

void MapCanvas::keyReleaseEvent( QKeyEvent * e )
{
	//QgsDebugMsg( "keyRelease event" );

	if ( _drawing )
	{
		return;
	}

	switch ( e->key() )
	{
	case Qt::Key_Space:
		if ( !e->isAutoRepeat() && _canvasProperties->panSelectorDown )
		{
			_canvasProperties->panSelectorDown = false;
			panActionEnd( _canvasProperties->mouseLastXY );
		}
		break;

	default:
		if ( _mapTool )
		{
			_mapTool->keyReleaseEvent( e );
		}

		e->ignore();
	}

	emit keyReleased( e );

}

void MapCanvas::mouseDoubleClickEvent( QMouseEvent * e )
{
	if ( _drawing )
	{
		return;
	}
	if ( _mapTool )	_mapTool->canvasDoubleClickEvent( e );
} 


void MapCanvas::mousePressEvent( QMouseEvent * e )
{
	if ( _drawing )
	{
		return;
	}

	//use middle mouse button for panning, map tools won't receive any events in that case
	if ( e->button() == Qt::MidButton )
	{
		_canvasProperties->panSelectorDown = true;
		_canvasProperties->rubberStartPoint = _canvasProperties->mouseLastXY;
	}
	else
	{
		// call handler of current map tool
		if ( _mapTool ) _mapTool->canvasPressEvent( e );
	}
	emit mousePressd(e);
	if ( _canvasProperties->panSelectorDown )
	{
		return;
	}

	_canvasProperties->mouseButtonDown = true;
	_canvasProperties->rubberStartPoint = e->pos();
	

} 

void MapCanvas::mouseReleaseEvent( QMouseEvent * e )
{
	if ( _drawing )
	{
		return;
	}

	//use middle mouse button for panning, map tools won't receive any events in that case
	if ( e->button() == Qt::MidButton )
	{
		_canvasProperties->panSelectorDown = false;
		panActionEnd( _canvasProperties->mouseLastXY );
	}
	else
	{
		_mapTool->canvasReleaseEvent( e );
	}
	_canvasProperties->mouseButtonDown = false;
	emit mouseReleased(e);

} // mouseReleaseEvent

void MapCanvas::resizeEvent( QResizeEvent *e )
{
	_newSize = e->size();
	emit screenSizeChanged(_newSize);
}

void MapCanvas::paintEvent( QPaintEvent *e )
{ 
	if(_newSize.isValid())
	{
		if ( (_painting || _drawing) && _map->mapRenderer())
		{
			//cancel current render progress
			
			RenderContext* theRenderContext = _map->mapRenderer()->renderContext();
			if ( theRenderContext )
			{
				theRenderContext->setRenderingStopped( true );
			}
			
			return;
		}
	}

	_painting = true;
	if(_newSize.isValid())
	{
		_map->resize(_newSize);
		_scene->setSceneRect( QRectF( 0, 0, _newSize.width(), _newSize.height() ) );
		// notify canvas items of change
		updateCanvasItemPositions();
		refresh();
		updateScale();
		_newSize = QSize();
	}	
	_painting = false;

	QGraphicsView::paintEvent( e );
} 

void MapCanvas::wheelEvent( QWheelEvent *e )
{
	// Zoom the map canvas in response to a mouse wheel event. Moving the
	// wheel forward (away) from the user zooms in

	if ( _drawing )
	{
		return;
	}

	switch ( _wheelAction )
	{
	case WheelZoom:
		// zoom without changing extent
		if ( e->delta() > 0 )
			zoomIn();
		else
			zoomOut();
		break;

	case WheelZoomAndRecenter:
		// zoom and don't change extent
		zoomWithCenter( e->x(), e->y(), e->delta() > 0 );
		break;

	case WheelZoomToMouseCursor:
		{
			// zoom map to mouse cursor
			double scaleFactor = e->delta() > 0 ? 1 / _wheelZoomFactor : _wheelZoomFactor;

			Point oldCenter( _map->mapRenderer()->extent().getCenter() );
			Point mousePos( getCoordinateTransform()->screenToMap( e->x(), e->y() ) );
			Point newCenter( mousePos.getX() + (( oldCenter.getX() - mousePos.getY() ) * scaleFactor ),
				mousePos.getY() + (( oldCenter.getY() - mousePos.getY() ) * scaleFactor ) );

			// same as zoomWithCenter (no coordinate transformations are needed)
			Envelope extent = _map->mapRenderer()->extent();
			extent.scale( scaleFactor, &newCenter );
			setExtent( extent );
			refresh();
			break;
		}

	case WheelNothing:
		// well, nothing!
		break;
	}

	_mapTool->canvasWheelEvent(e);
}

void MapCanvas::setWheelAction( WheelAction action, double factor )
{
	_wheelAction = action;
	_wheelZoomFactor = factor;
}

void MapCanvas::zoomIn()
{
	zoomByFactor( 1 / _wheelZoomFactor );
}

void MapCanvas::zoomOut()
{
	zoomByFactor( _wheelZoomFactor );
}

void MapCanvas::zoomScale( double newScale )
{
	zoomByFactor( newScale / scale() );
}

void MapCanvas::zoomWithCenter( int x, int y, bool zoomIn )
{
	if ( _drawing )
	{
		return;
	}

	double scaleFactor = ( zoomIn ? 1 / _wheelZoomFactor : _wheelZoomFactor );

	// transform the mouse pos to map coordinates
	Point center  = getCoordinateTransform()->screenToMap( x, y );
	Envelope r = _map->mapRenderer()->extent();
	r.scale( scaleFactor, &center );
	setExtent( r );
	refresh();
}

void MapCanvas::mouseMoveEvent( QMouseEvent * e )
{
	if ( _drawing )
	{
		return;
	}

	_canvasProperties->mouseLastXY = e->pos();

	if ( _canvasProperties->panSelectorDown )
	{
		panAction( e );
	}
	else
	{
		// call handler of current map tool
		if ( _mapTool ) _mapTool->canvasMoveEvent( e );
		//if(_compass)_compass->update();
	}

	// show x y on status bar
	QPoint xy = e->pos();
	Point coord = getCoordinateTransform()->screenToMap( xy );
	emit mapCoordinate( coord.getX(), coord.getY() );
	emit screenCoordinate(xy.x(), xy.y());
	emit mouseMoved(e);
} // mouseMoveEvent



/** Sets the map tool currently being used on the canvas */
void MapCanvas::setMapTool( MapTool* tool )
{
	if ( !tool )
		return;

	if ( _mapTool )
	{
		disconnect( _mapTool, SIGNAL( destroyed() ), this, SLOT( mapToolDestroyed() ) );
		_mapTool->deactivate();
	}

	if ( tool->isTransient() && _mapTool && !_mapTool->isTransient() )
	{
		// if zoom or pan tool will be active, save old tool
		// to bring it back on right click
		// (but only if it wasn't also zoom or pan tool)
		_lastNonZoomMapTool = _mapTool;
	}
	else
	{
		_lastNonZoomMapTool = NULL;
	}

	// set new map tool and activate it
	_mapTool = tool;
	if ( _mapTool )
	{
		connect( _mapTool, SIGNAL( destroyed() ), this, SLOT( mapToolDestroyed() ) );
		_mapTool->activate();
	}

	//emit mapToolSet( _mapTool );
}

void MapCanvas::unsetMapTool(MapTool* tool )
{
	if ( _mapTool && _mapTool == tool )
	{
		_mapTool->deactivate();
		_mapTool = NULL;
		emit mapToolSet( NULL );
		setCursor( Qt::ArrowCursor );
	}

	if ( _lastNonZoomMapTool && _lastNonZoomMapTool == tool )
	{
		_lastNonZoomMapTool = NULL;
	}
}

void MapCanvas::setCanvasColor( const QColor & theColor )
{
	// background of map's pixmap
	_map->setBackgroundColor( theColor );

}

void MapCanvas::freeze( bool frz )
{
	_frozen = frz;
} 

bool MapCanvas::isFrozen()
{
	return _frozen;
}


QPixmap& MapCanvas::canvasPixmap()
{
	QPixmap *pixmap = dynamic_cast<QPixmap *>( &canvasPaintDevice() );
	if ( pixmap )
	{
		return *pixmap;
	}
	static QPixmap staticPixmap;
	QImage *image = dynamic_cast<QImage *>( &_map->paintDevice() );
	if ( image )
	{
		staticPixmap = QPixmap::fromImage( *image );
	}
	else
	{
		staticPixmap = QPixmap( canvasPaintDevice().width(), canvasPaintDevice().height() );
	}

	return staticPixmap;
} 

QPaintDevice &MapCanvas::canvasPaintDevice()
{
	return _map->paintDevice();
}

double MapCanvas::mapUnitsPerPixel() const
{
	return _map->mapRenderer()->mapUnitsPerPixel();
}

void MapCanvas::setRenderFlag( bool theFlag )
{
	_renderFlag = theFlag;
	if ( _map->mapRenderer() )
	{
		RenderContext* rc = _map->mapRenderer()->renderContext();
		if ( rc )
		{
			rc->setRenderingStopped( !theFlag );
		}
	}

	if ( _renderFlag )
	{
		refresh();
	}
}

MapTool* MapCanvas::mapTool()
{
	return _mapTool;
}

void MapCanvas::panActionEnd( QPoint releasePoint )
{
	if ( _drawing )
	{
		return;
	}
	moveCanvasContents( true );
	// use start and end box points to calculate the extent
	Point start = getCoordinateTransform()->screenToMap( _canvasProperties->rubberStartPoint );
	Point end = getCoordinateTransform()->screenToMap( releasePoint );

	double dx = qAbs( end.getX() - start.getX() );
	double dy = qAbs( end.getY() - start.getY() );

	// modify the extent
	Envelope r = _map->mapRenderer()->extent();

	if ( end.getX() < start.getX() )
	{
		r.setMinX( r.getMinX() + dx );
		r.setMaxX( r.getMaxX() + dx );
	}
	else
	{
		r.setMinX( r.getMinX() - dx );
		r.setMaxX( r.getMaxX() - dx );
	}

	if ( end.getY() < start.getY() )
	{
		r.setMaxY( r.getMaxY() + dy );
		r.setMinY( r.getMinY() + dy );

	}
	else
	{
		r.setMaxY( r.getMaxY() - dy );
		r.setMinY( r.getMinY() - dy );

	}

	setExtent( r );
	refresh();
}

void MapCanvas::panAction( QMouseEvent * e )
{
	Q_UNUSED( e );
	if ( _drawing )
	{
		return;
	}
	moveCanvasContents();
	
	// update canvas
	//updateContents(); // TODO: need to update?
}

QPoint MapCanvas::mouseLastXY()
{
	return _canvasProperties->mouseLastXY;
}

void MapCanvas::zoomByFactor( double scaleFactor )
{
	if ( _drawing )
	{
		return;
	}

	Envelope r = _map->mapRenderer()->extent();
	r.scale( scaleFactor );
	setExtent( r );
	refresh();
}

void MapCanvas::dragEnterEvent( QDragEnterEvent * e )
{
	e->ignore();
}

void MapCanvas::mapToolDestroyed()
{
	_mapTool = nullptr;
}

void MapCanvas::moveCanvasContents( bool reset /*= false */ )
{
	if (_drawing ) return;

	QPoint pnt( 0, 0 );
	if ( !reset )
		pnt += _canvasProperties->mouseLastXY - _canvasProperties->rubberStartPoint;

	_map->setPanningOffset( pnt );

	QList<QGraphicsItem*> list = _scene->items();
	QList<QGraphicsItem*>::iterator it = list.begin();
	while ( it != list.end() )
	{
		QGraphicsItem* item = *it;

		if ( item != _map )
		{
			// this tells map canvas item to draw with offset
			MapCanvasItem* canvasItem = dynamic_cast<MapCanvasItem *>( item );
			if ( canvasItem ) canvasItem->setPanningOffset( pnt );
		}

		it++;
	}	
	// show items
	updateCanvasItemPositions();
}

void MapCanvas::updateCanvasItemPositions()
{
	QList<QGraphicsItem*> list = _scene->items();
	QList<QGraphicsItem*>::iterator it = list.begin();
	while ( it != list.end() )
	{
		MapCanvasItem* item = dynamic_cast<MapCanvasItem *>( *it );

		if ( item )
		{
			item->updatePosition();
		}
		else
		{
			(*it)->update();
		}
		
		it++;
	}
}

void MapCanvas::addRenderer( Renderer* renderer )
{
	_map->mapRenderer()->addRenderer(renderer);
	refresh();
}


void MapCanvas::removeRenderer( Renderer * renderer )
{
	_map->mapRenderer()->removeRenderer(renderer);
	refresh();
}


void MapCanvas::addGraphicsItem( QGraphicsItem* item )
{
	_scene->addItem(item);
}

void MapCanvas::fullExtent()
{
	setExtent(mapRenderer()->getFullExtent());
	refresh();
}

void MapCanvas::clearRenderers()
{
	_map->clearRenderers();
}

void MapCanvas::createMapTools(MapActions* mapActions)
{
	_mapTool = nullptr;
	_lastNonZoomMapTool = nullptr;

	_mapTools.pan = new MapToolPan(this);
	_mapTools.pan->setAction(mapActions->getActionPan());

	_mapTools.selectPoint = new MapToolSelectPoint(this);
	_mapTools.selectPoint->setAction(mapActions->getActionSelectPoint());

	_mapTools.selectPolygon = new MapToolSelectPolygon(this);
	_mapTools.selectPolygon->setAction(mapActions->getActionSelectPolygon());

	_mapTools.selectRectangle = new MapToolSelectRectangle(this);
	_mapTools.selectRectangle->setAction(mapActions->getActionSelectRectangle());

	_mapTools.zoomIn = new MapToolZoom(this, false);
	_mapTools.zoomIn->setAction(mapActions->getActionZoomIn());

	_mapTools.zoomOut = new MapToolZoom(this, true);
	_mapTools.zoomOut->setAction(mapActions->getActionZoomOut());

	_mapTools.measureArea = new MeasureTool(this, true);
	_mapTools.measureArea->setAction(mapActions->getActionMearureArea());

	_mapTools.drawPolygon = new MapToolDrawPolygon(this);
	_mapTools.drawPolygon->setAction(mapActions->getActionDrawPolygon());
}

void MapCanvas::connectActionsSignalSlot()
{
	connect(_mapActions->getActionPan(), SIGNAL( triggered() ), this, SLOT( panMapTool() ) );
	connect(_mapActions->getActionZoomIn(), SIGNAL( triggered() ), this, SLOT( zoomInMapTool() ) );
	connect(_mapActions->getActionZoomOut(), SIGNAL( triggered() ), this, SLOT( zoomOutMapTool() ) );
	connect(_mapActions->getActionSelectPoint(), SIGNAL( triggered() ), this, SLOT( selectByPoint() ) );
	connect(_mapActions->getActionSelectRectangle(), SIGNAL( triggered() ), this, SLOT( selectByRectangle() ) );
	connect(_mapActions->getActionSelectPolygon(), SIGNAL( triggered() ), this, SLOT( selectByPolygon() ) );
	connect(_mapActions->getActionZoomFullExtent(), SIGNAL( triggered() ), this, SLOT( fullExtent()) );
	connect(_mapActions->getActionDeselectAll(), SIGNAL(triggered()), this, SLOT(deselect()));
	connect(_mapActions->getActionMearureArea(), SIGNAL(triggered()), this, SLOT(measureArea()));
	connect(_mapActions->getActionDrawPolygon(), SIGNAL(triggered()), this, SLOT(drawPolygon()));
}

void MapCanvas::zoomOutMapTool()
{
	setMapTool(_mapTools.zoomOut);
}

void MapCanvas::zoomInMapTool()
{
	setMapTool(_mapTools.zoomIn);
}

void MapCanvas::panMapTool()
{
	setMapTool(_mapTools.pan);
}

void MapCanvas::selectByRectangle()
{
	setMapTool(_mapTools.selectRectangle);
}

void MapCanvas::selectByPolygon()
{
	setMapTool(_mapTools.selectPolygon);
}


void MapCanvas::selectByPoint()
{
	setMapTool(_mapTools.selectPoint);
}


void MapCanvas::setSelectPolygon( const Polygon& selectPolygon )
{
	mapRenderer()->setSelectPolygon(selectPolygon);
	emit polygonSelected(selectPolygon);
	refresh();
}


void MapCanvas::setSelectPoint( const Point& selectPoint )
{
	mapRenderer()->setSelectPoint(selectPoint);
	emit pointSelected(selectPoint);
	refresh();
}


void MapCanvas::deselect()
{
	mapRenderer()->deselect();
	_mapTool->reset();
	refresh();
	emit deselected();

}

void MapCanvas::setSelectRubberBandColor( const QColor& color )
{
	MapControlConfig::getInstance()->setSelectRubberBandColor(color);
}

void MapCanvas::centerOn( const Point& point )
{
	Envelope extent = this->extent();
	double width = extent.getWidth();
	double height = extent.getHeight();

	Envelope newExtent;
	newExtent.setMinX(point.getX() - width / 2);
	newExtent.setMinY(point.getY() - height / 2);
	newExtent.setMaxX(point.getX() + width / 2);
	newExtent.setMaxY(point.getY() + height / 2);

	setExtent(newExtent);
}

void MapCanvas::setMapToolType( MapToolType toolType )
{
	switch(toolType)
	{
	case MapTool_Pan:
		panMapTool();
		break;
	case MapTool_ZoomIn:
		zoomInMapTool();
		break;
	case MapTool_ZoomOut:
		zoomOutMapTool();
		break;
	case  MapTool_SelectPolygon:
		selectByPolygon();
		break;
	case  MapTool_SelectRectangle:
		selectByRectangle();
		break;
	case MapTool_SelectPoint:
		selectByPoint();
		break;
	case MapTool_MeasureArea:
		measureArea();
		break;
	case MapTool_DrawPolygon:
		drawPolygon();
		break;
	default:
		panMapTool();
	}
}

void MapCanvas::measureArea()
{
	setMapTool(_mapTools.measureArea);
}

void MapCanvas::setMapToolBarVisible( bool visible )
{
	getMapToolBar()->setVisible(visible);
}

const RenderContext* MapCanvas::renderContext() const
{
	return _map->renderContext();
}

RendererList* MapCanvas::getRenderers()
{
	return mapRenderer()->getRenderers();
}

const RendererList* MapCanvas::getRenderers() const
{
	return mapRenderer()->getRenderers();
}

void MapCanvas::setDrawPolygon( const Polygon& drawedPolygon )
{
	mapRenderer()->setDrawPolygon(drawedPolygon);
	emit polygonDrawed(drawedPolygon);
	refresh();
}

void MapCanvas::drawPolygon()
{
	setMapTool(_mapTools.drawPolygon);
}

}//MapControl
}//TGS